<!DOCTYPE html>
<html  lang="zh-CN" >
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, maximum-scale=5, viewport-fit=cover">
    <title>ESP-IDF学习笔记-IIC与FT6236触摸屏 | LO_StacNet的火柴盒</title>
    <meta name="description" content="ESP-IDF学习笔记-IIC与FT6236触摸屏FT6236是一个电容屏驱动芯片，支持单点+手势或者双点触控，基于I2C协议。本篇将在ESP32C3下基于IDF开发其驱动。同时学习IIC驱动的使用。">
<meta property="og:type" content="article">
<meta property="og:title" content="ESP-IDF学习笔记-IIC与FT6236触摸屏">
<meta property="og:url" content="https://lostacnet.top/post/43032/">
<meta property="og:site_name" content="LO_StacNet的火柴盒">
<meta property="og:description" content="ESP-IDF学习笔记-IIC与FT6236触摸屏FT6236是一个电容屏驱动芯片，支持单点+手势或者双点触控，基于I2C协议。本篇将在ESP32C3下基于IDF开发其驱动。同时学习IIC驱动的使用。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://s21.ax1x.com/2024/08/13/pApb4r4.png">
<meta property="og:image" content="https://s21.ax1x.com/2024/08/13/pApb5qJ.png">
<meta property="og:image" content="https://s21.ax1x.com/2024/08/13/pApbTaR.png">
<meta property="og:image" content="https://s21.ax1x.com/2024/08/13/pApb7I1.png">
<meta property="og:image" content="https://s21.ax1x.com/2024/08/13/pApbbPx.png">
<meta property="article:published_time" content="2024-04-29T17:32:28.000Z">
<meta property="article:modified_time" content="2024-08-13T07:53:09.139Z">
<meta property="article:author" content="LO_StacNet">
<meta property="article:tag" content="ESP-IDF">
<meta property="article:tag" content="ESP32">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://s21.ax1x.com/2024/08/13/pApb4r4.png">

    
    <link rel="icon" href="/images/favicon.ico" type="image/x-icon">

    
<link rel="stylesheet" href="/css/common.min.css">



    
        <link href="//cdn.jsdelivr.net/npm/katex@0.9.0/dist/katex.min.css" rel="stylesheet">
    
    
    
    
        <link href="//cdn.jsdelivr.net/npm/lightgallery.js@1.1.3/dist/css/lightgallery.min.css" rel="stylesheet">
    
    
    
<link rel="stylesheet" href="/css/iconfont.min.css">

    
<meta name="generator" content="Hexo 6.3.0"><style>mjx-container[jax="SVG"] {
  direction: ltr;
}

mjx-container[jax="SVG"] > svg {
  overflow: visible;
}

mjx-container[jax="SVG"][display="true"] {
  display: block;
  text-align: center;
  margin: 1em 0;
}

mjx-container[jax="SVG"][justify="left"] {
  text-align: left;
}

mjx-container[jax="SVG"][justify="right"] {
  text-align: right;
}

g[data-mml-node="merror"] > g {
  fill: red;
  stroke: red;
}

g[data-mml-node="merror"] > rect[data-background] {
  fill: yellow;
  stroke: none;
}

g[data-mml-node="mtable"] > line[data-line] {
  stroke-width: 70px;
  fill: none;
}

g[data-mml-node="mtable"] > rect[data-frame] {
  stroke-width: 70px;
  fill: none;
}

g[data-mml-node="mtable"] > .mjx-dashed {
  stroke-dasharray: 140;
}

g[data-mml-node="mtable"] > .mjx-dotted {
  stroke-linecap: round;
  stroke-dasharray: 0,140;
}

g[data-mml-node="mtable"] > svg {
  overflow: visible;
}

[jax="SVG"] mjx-tool {
  display: inline-block;
  position: relative;
  width: 0;
  height: 0;
}

[jax="SVG"] mjx-tool > mjx-tip {
  position: absolute;
  top: 0;
  left: 0;
}

mjx-tool > mjx-tip {
  display: inline-block;
  padding: .2em;
  border: 1px solid #888;
  font-size: 70%;
  background-color: #F8F8F8;
  color: black;
  box-shadow: 2px 2px 5px #AAAAAA;
}

g[data-mml-node="maction"][data-toggle] {
  cursor: pointer;
}

mjx-status {
  display: block;
  position: fixed;
  left: 1em;
  bottom: 1em;
  min-width: 25%;
  padding: .2em .4em;
  border: 1px solid #888;
  font-size: 90%;
  background-color: #F8F8F8;
  color: black;
}

foreignObject[data-mjx-xml] {
  font-family: initial;
  line-height: normal;
  overflow: visible;
}

.MathJax path {
  stroke-width: 3;
}

mjx-container[display="true"] {
  overflow: auto hidden;
}

mjx-container[display="true"] + br {
  display: none;
}
</style></head>

    <body>
        <header class="header header-fixture">
    <div class="profile-search-wrap flex sm:block">
        
        
        <div class="profile sm:text-center md:px-1 lg:px-3 sm:pb-4 sm:pt-6">
            <a id="avatar" role="link" href="http://www.lostacnet.top" class="inline-block lg:w-16 lg:h-16 w-8 h-8 m-2" target="_blank" rel="noopener" rel="noreferrer" >
                <img src="/images/avatar.jpg" class="rounded-full" alt="avatar">
            </a>
            <h2 id="name" class="hidden lg:block">LO_StacNet</h2>
            <h3 id="title" class="hidden lg:block">电子玩家 &amp; 理想主义</h3>
            
            <small id="location" class="hidden lg:block">
                <i class="iconfont icon-map-icon"></i>
                Sichuan, China
            </small>
            
        </div>
        
        
<div class="search flex-1 flex lg:inline-block sm:hidden lg:px-4 lg:mt-2 lg:mb-4 lg:w-full">
    <form id="search-form" class="my-auto flex-1 lg:border lg:border-solid lg:border-gray-200">
        <div class="input-group table bg-gray-100 lg:bg-white w-full">
            <input id="search-input" type="text" placeholder="搜索" class="inline-block w-full bg-gray-100 lg:bg-white p-1">
            <span class="table-cell">
                <button name="search tigger button" disabled>
                    <i class="iconfont icon-search m-2"></i>
                </button>
            </span>
        </div>
    </form>
        
<div id="content-json" data-placeholder="搜索" class="invisible hidden">/content.json</div>
<script id="search-teamplate" type="text/html" data-path="/content.json">
    <div>
        <div class="search-header bg-gray-400">
            <input id="actual-search-input" model="keyword" ref="input" class="inline-block w-full h-10 px-2 py-1" placeholder="搜索" type="text">
        </div>
        <div class="search-result bg-gray-200">
            {{#each searchPosts}}
            <a href="/{{ path }}" class="result-item block px-2 pb-3 mb-1 pt-1 hover:bg-indigo-100">
                <i class="iconfont icon-file"></i>
                <h1 class="result-title inline font-medium text-lg">{{ title }}</h1>
                <p class="result-content text-gray-600 text-sm">{{{ text }}}</p>
            </a>
            {{/each}}
        </div>
    </div>
</script>

</div>


        <button name="menu toogle button" id="menu-toggle-btn" class="block sm:hidden p-3" role="button" aria-expanded="false">
            <i class="iconfont icon-hamburger"></i>
        </button>
    </div>
    <nav id="menu-nav" class="hidden sm:flex flex-col">
        
        
            <div class="menu-item menu-home" role="menuitem">
                <a href="/.">
                    <i class="iconfont icon-home" aria-hidden="true"></i>
                    <span class="menu-title">首页</span>
                </a>
            </div>
        
        
            <div class="menu-item menu-archives" role="menuitem">
                <a href="/archives">
                    <i class="iconfont icon-archive" aria-hidden="true"></i>
                    <span class="menu-title">归档</span>
                </a>
            </div>
        
        
            <div class="menu-item menu-categories" role="menuitem">
                <a href="/categories">
                    <i class="iconfont icon-folder" aria-hidden="true"></i>
                    <span class="menu-title">分类</span>
                </a>
            </div>
        
        
            <div class="menu-item menu-tags" role="menuitem">
                <a href="/tags">
                    <i class="iconfont icon-tag" aria-hidden="true"></i>
                    <span class="menu-title">标签</span>
                </a>
            </div>
        
        
            <div class="menu-item menu-links" role="menuitem">
                <a href="/links">
                    <i class="iconfont icon-friend" aria-hidden="true"></i>
                    <span class="menu-title">友链</span>
                </a>
            </div>
        
        
            <div class="menu-item menu-about" role="menuitem">
                <a href="/about">
                    <i class="iconfont icon-cup" aria-hidden="true"></i>
                    <span class="menu-title">关于</span>
                </a>
            </div>
        
        
<div class="social-links flex sm:flex-col lg:hidden mt-5">
    
        <span class="social-item text-center">
            <a target="_blank" rel="noopener" href="https://github.com/LOStacNet">
                <i class="iconfont social-icon icon-github"></i>
                <span class="menu-title hidden lg:inline">menu.github</span>
            </a>
        </span>
    
        <span class="social-item text-center">
            <a target="_blank" rel="noopener" href="https://gitee.com/LOStacNet">
                <i class="iconfont social-icon icon-project"></i>
                <span class="menu-title hidden lg:inline">menu.project</span>
            </a>
        </span>
    
</div>


    </nav>
</header>

        <section class="main-section">
            
    <main class="flex-1 px-4 py-14 md:px-5 lg:px-8 lg:py-4 relative min-h-screen">
    

    <article class="content article article-archives article-type-list" itemscope="">
        <header class="article-header">
            
    
        <h1 class="article-title text-lg" itemprop="name">
            ESP-IDF学习笔记-IIC与FT6236触摸屏
        </h1>
    



            <p class="article-meta mb-3 text-xs">
                <span class="article-date">
    <i class="iconfont icon-calendar-check"></i>
	<a href="/post/43032/" class="article-date">
	  <time datetime="2024-04-29T17:32:28.000Z" itemprop="datePublished">4月 30</time>
	</a>
</span>

                
    <span class="article-category">
    <i class="iconfont icon-folder"></i>
    <a class="article-category-link" href="/categories/ESP32%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">ESP32学习笔记</a>
  </span>


                
    <span class="article-tags">
    <i class="iconfont icon-tag"></i>
    <a class="article-tag-none-link" href="/tags/ESP-IDF/" rel="tag">ESP-IDF</a>, <a class="article-tag-none-link" href="/tags/ESP32/" rel="tag">ESP32</a>
  </span>


                <span class="_partial/post-comment"><i class="icon icon-comment"></i>
                    <a href="/post/43032/#comments" class="article-comment-link">
                        评论
                    </a>
                </span>
                
    
        <span class="post-wordcount" itemprop="wordCount">字数统计: 3.2k(字)</span>
    
    
        <span class="post-readcount" itemprop="timeRequired">阅读时长: 15(分)</span>
    


            </p>
        </header>
        <div class="marked-body article-body">
            <h1 id="ESP-IDF学习笔记-IIC与FT6236触摸屏"><a href="#ESP-IDF学习笔记-IIC与FT6236触摸屏" class="headerlink" title="ESP-IDF学习笔记-IIC与FT6236触摸屏"></a>ESP-IDF学习笔记-IIC与FT6236触摸屏</h1><p>FT6236是一个电容屏驱动芯片，支持单点+手势或者双点触控，基于I2C协议。本篇将在ESP32C3下基于IDF开发其驱动。同时学习IIC驱动的使用。</p>
<span id="more"></span>

<h2 id="官方文档"><a href="#官方文档" class="headerlink" title="官方文档"></a>官方文档</h2><p><a target="_blank" rel="noopener" href="https://focuslcds.com/wp-content/uploads/Drivers/FT6236.pdf">datasheet</a></p>
<p><a target="_blank" rel="noopener" href="https://docs.espressif.com/projects/esp-idf/zh_CN/v5.1.3/esp32c3/api-reference/peripherals/i2c.html">I2C驱动程序</a></p>
<h2 id="IDF的IIC驱动"><a href="#IDF的IIC驱动" class="headerlink" title="IDF的IIC驱动"></a>IDF的IIC驱动</h2><p>ESP32-C3拥有一个IIC控制器，IDF为其提供了完整的驱动。</p>
<h3 id="版本变更"><a href="#版本变更" class="headerlink" title="版本变更"></a>版本变更</h3><p>在最新版的IDF中，IIC驱动分为新驱动和老驱动，他们在对用户开放的API上有所不同。老驱动引用头文件<code>driver/i2c.h</code>，新驱动则是<code>i2c_master.h</code>，<code>i2c_slave.h</code>。本文使用老驱动。</p>
<h3 id="配置驱动程序"><a href="#配置驱动程序" class="headerlink" title="配置驱动程序"></a>配置驱动程序</h3><p>建立IIC通信的第一步是配置驱动程序，使用<code>i2c_config_t</code>结构体以及<code>i2c_param_config() </code>函数进行设置。</p>
<p>i2c_config_t:</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span>{</span></span><br><span class="line">    <span class="type">i2c_mode_t</span> mode;     <span class="comment">/*!&lt; I2C mode */</span></span><br><span class="line">    <span class="type">int</span> sda_io_num;      <span class="comment">/*!&lt; GPIO number for I2C sda signal */</span></span><br><span class="line">    <span class="type">int</span> scl_io_num;      <span class="comment">/*!&lt; GPIO number for I2C scl signal */</span></span><br><span class="line">    <span class="type">bool</span> sda_pullup_en;  <span class="comment">/*!&lt; Internal GPIO pull mode for I2C sda signal*/</span></span><br><span class="line">    <span class="type">bool</span> scl_pullup_en;  <span class="comment">/*!&lt; Internal GPIO pull mode for I2C scl signal*/</span></span><br><span class="line"></span><br><span class="line">    <span class="class"><span class="keyword">union</span> {</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line">            <span class="type">uint32_t</span> clk_speed;      <span class="comment">/*!&lt; I2C clock frequency for master mode, (no higher than 1MHz for now) */</span></span><br><span class="line">        } master;                    <span class="comment">/*!&lt; I2C master config */</span></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> SOC_I2C_SUPPORT_SLAVE</span></span><br><span class="line">        <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line">            <span class="type">uint8_t</span> addr_10bit_en;   <span class="comment">/*!&lt; I2C 10bit address mode enable for slave mode */</span></span><br><span class="line">            <span class="type">uint16_t</span> slave_addr;     <span class="comment">/*!&lt; I2C address for slave mode */</span></span><br><span class="line">            <span class="type">uint32_t</span> maximum_speed;  <span class="comment">/*!&lt; I2C expected clock speed from SCL. */</span></span><br><span class="line">        } slave;                     <span class="comment">/*!&lt; I2C slave config */</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span> <span class="comment">// SOC_I2C_SUPPORT_SLAVE</span></span></span><br><span class="line">    };</span><br><span class="line">    <span class="type">uint32_t</span> clk_flags;              <span class="comment">/*!&lt; Bitwise of ``I2C_SCLK_SRC_FLAG_**FOR_DFS**`` for clk source choice*/</span></span><br><span class="line">} <span class="type">i2c_config_t</span>;</span><br></pre></td></tr></table></figure>

<p>上述结构中，我们需要关注以下几个成员：</p>
<ul>
<li><code>mode</code>:选择I2C的模式，可选参数为：<code>I2C_MODE_SLAVE</code>,<code>I2C_MODE_MASTER</code>。</li>
<li><code>sda\scl_io_num</code>:信号线引脚</li>
<li><code>sda\scl_pullup_en</code>:内部上拉使能</li>
<li><code>master.clk_speed</code>:时钟频率</li>
</ul>
<p>从模式本次暂不涉及。<code>clk_flags</code>用以选择时钟源，一般默认0即可。</p>
<p>设置完成后调用函数进行设置：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">esp_err_t</span> <span class="title function_">i2c_param_config</span><span class="params">(<span class="type">i2c_port_t</span> i2c_num, <span class="type">const</span> <span class="type">i2c_config_t</span> *i2c_conf)</span></span><br></pre></td></tr></table></figure>

<p><code>i2c_num</code>标识了使用芯片的哪一个I2C控制器。该函数还设置了I2C标准的一些默认参数(高低电平时间，起始信号时序等)，想要修改这些参数可以在<a target="_blank" rel="noopener" href="https://docs.espressif.com/projects/esp-idf/zh_CN/v5.1.3/esp32c3/api-reference/peripherals/i2c.html#i2c-api-customized-configuration">用户自定义配置</a>进行查看。</p>
<h3 id="安装驱动程序"><a href="#安装驱动程序" class="headerlink" title="安装驱动程序"></a>安装驱动程序</h3><p>配置完成后，调用函数安装驱动：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">esp_err_t</span> <span class="title function_">i2c_driver_install</span><span class="params">(<span class="type">i2c_port_t</span> i2c_num, <span class="type">i2c_mode_t</span> mode, <span class="type">size_t</span> slv_rx_buf_len, <span class="type">size_t</span> slv_tx_buf_len,<span class="type">int</span> intr_alloc_flags)</span></span><br></pre></td></tr></table></figure>

<p><code>i2c_num</code>为上面使用的I2C控制器代号，<code>mod</code>为模式选择。</p>
<p>buf_len参数为从模式下用以缓存数据，主模式不用管。<code>intr_alloc_flags</code>设置中断分配的标志，这里为0即可。</p>
<h3 id="主机模式下的通信"><a href="#主机模式下的通信" class="headerlink" title="主机模式下的通信"></a>主机模式下的通信</h3><p>这里我们只考虑主机通信这一常用模式。</p>
<p>I2C的驱动使用了一个命令容器的机制，用户首先创建一个命令容器，然后将要进行的各种I2C动作(包括开始时序、写地址、写数据、读数据等)依次填入命令容器，最后执行命令容器，将所有操纵传递给控制器执行，具体过程如下图所示：</p>
<h4 id="主机写入数据"><a href="#主机写入数据" class="headerlink" title="主机写入数据"></a>主机写入数据</h4><p><img src="https://s21.ax1x.com/2024/08/13/pApb4r4.png" alt="image-20240813133014080"></p>
<h4 id="主机读取数据"><a href="#主机读取数据" class="headerlink" title="主机读取数据"></a>主机读取数据</h4><p><img src="https://s21.ax1x.com/2024/08/13/pApb5qJ.png" alt="image-20240813133043479"></p>
<ul>
<li>命令容器的创建</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">i2c_cmd_handle_t</span> handle = i2c_cmd_link_create();</span><br></pre></td></tr></table></figure>

<p>该命令会动态的分配一段内存创建命令容器。如果不想使用动态内存分配，可以使用静态创建方式：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">uint8_t</span> buffer[I2C_TRANS_BUF_MINIMUM_SIZE] = { <span class="number">0</span> };</span><br><span class="line"></span><br><span class="line"><span class="type">i2c_cmd_handle_t</span> handle = i2c_cmd_link_create_static(buffer, <span class="keyword">sizeof</span>(buffer));</span><br></pre></td></tr></table></figure>

<ul>
<li>发送开始时序</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">err = i2c_master_start(handle);</span><br></pre></td></tr></table></figure>

<ul>
<li>写单个字节——发送地址</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//进行写操作</span></span><br><span class="line">err = i2c_master_write_byte(handle, device_address &lt;&lt; <span class="number">1</span> | I2C_MASTER_WRITE, ACK_EN);</span><br><span class="line"><span class="comment">//进行读操作</span></span><br><span class="line">err = i2c_master_write_byte(handle, device_address &lt;&lt; <span class="number">1</span> | I2C_MASTER_READ, ACK_EN);</span><br></pre></td></tr></table></figure>

<ul>
<li>读写数据</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//写操作</span></span><br><span class="line">err = i2c_master_write(handle, write_buffer, write_size, ACK_EN);</span><br><span class="line"><span class="comment">//读操作</span></span><br><span class="line">err = i2c_master_read(handle, read_buffer, read_size, I2C_MASTER_LAST_NACK);</span><br><span class="line"><span class="comment">//读单个字节</span></span><br><span class="line">err = i2c_master_read_byte(handle, &amp;read_buffer, I2C_MASTER_LAST_NACK);</span><br></pre></td></tr></table></figure>

<p><code> i2c_ack_type_t</code>规定了如何进行ACK相应，有三类：<code>I2C_MASTER_ACK</code>为每个直接响应ACK，<code>I2C_MASTER_NACK</code>为每个字节响应NACK，<code>I2C_MASTER_LAST_NACK</code>最后一个字节响应NACK。</p>
<ul>
<li>结束时序</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">i2c_master_stop(handle);</span><br></pre></td></tr></table></figure>

<ul>
<li>执行命令</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">err = i2c_master_cmd_begin(i2c_num, handle, ticks_to_wait);</span><br></pre></td></tr></table></figure>

<ul>
<li>释放命令容器内存</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//释放动态</span></span><br><span class="line">i2c_cmd_link_delete(handle);</span><br><span class="line"><span class="comment">//释放静态内存</span></span><br><span class="line">i2c_cmd_link_delete_static(handle);</span><br></pre></td></tr></table></figure>

<h3 id="删除驱动"><a href="#删除驱动" class="headerlink" title="删除驱动"></a>删除驱动</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">i2c_driver_delete(I2C_MASTER_NUM);</span><br></pre></td></tr></table></figure>

<p>释放资源。该函数无法保证线程安全。</p>
<h3 id="其他读写函数"><a href="#其他读写函数" class="headerlink" title="其他读写函数"></a>其他读写函数</h3><p>驱动中提供了一些预制的命令容器读写函数,可以满足一些常见的读写需求，函数如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">esp_err_t</span> <span class="title function_">i2c_master_write_to_device</span><span class="params">(<span class="type">i2c_port_t</span> i2c_num, <span class="type">uint8_t</span> device_address,</span></span><br><span class="line"><span class="params">                                     <span class="type">const</span> <span class="type">uint8_t</span>* write_buffer, <span class="type">size_t</span> write_size,</span></span><br><span class="line"><span class="params">                                     TickType_t ticks_to_wait)</span>;</span><br><span class="line"><span class="type">esp_err_t</span> <span class="title function_">i2c_master_read_from_device</span><span class="params">(<span class="type">i2c_port_t</span> i2c_num, <span class="type">uint8_t</span> device_address,</span></span><br><span class="line"><span class="params">                                      <span class="type">uint8_t</span>* read_buffer, <span class="type">size_t</span> read_size,</span></span><br><span class="line"><span class="params">                                      TickType_t ticks_to_wait)</span>;</span><br><span class="line"><span class="type">esp_err_t</span> <span class="title function_">i2c_master_write_read_device</span><span class="params">(<span class="type">i2c_port_t</span> i2c_num, <span class="type">uint8_t</span> device_address,</span></span><br><span class="line"><span class="params">                                       <span class="type">const</span> <span class="type">uint8_t</span>* write_buffer, <span class="type">size_t</span> write_size,</span></span><br><span class="line"><span class="params">                                       <span class="type">uint8_t</span>* read_buffer, <span class="type">size_t</span> read_size,</span></span><br><span class="line"><span class="params">                                       TickType_t ticks_to_wait)</span>;</span><br></pre></td></tr></table></figure>

<p>其中i2c_master_read_from_device的时序满足的是EEPROM的随机读时序(写完寄存器地址后直接发送Start信号)。</p>
<h2 id="FT6236"><a href="#FT6236" class="headerlink" title="FT6236"></a>FT6236</h2><h3 id="引脚定义"><a href="#引脚定义" class="headerlink" title="引脚定义"></a>引脚定义</h3><p>FT6236触摸屏一共有6个引脚，除去3.3V供电和GND以外，还有以下几个：</p>
<ul>
<li><code>SDA</code>:IIC的数据线，需要上拉到VCC。</li>
<li><code>SCL</code>:IIC的时钟线，需要上拉到VCC。</li>
<li><code>INT</code>:中断信号线，指示是否有触摸点，低电平有效，有触摸点时可以根据设置发出低脉冲或持续拉低。需要上拉到VCC。</li>
<li><code>RST</code>:复位信号线。低电平有效，需要持续低电平300ms以上，需要上拉到VCC。</li>
</ul>
<p>注意各个信号线的上拉，这很重要。</p>
<h3 id="设备结构体"><a href="#设备结构体" class="headerlink" title="设备结构体"></a>设备结构体</h3><p>设置一个数据结构体作为一个设备的实例。 </p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line">    <span class="type">int8_t</span> int_pin;</span><br><span class="line">    <span class="type">int8_t</span> rst_pin;</span><br><span class="line">    <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line">        <span class="type">uint8_t</span> sda_pin;</span><br><span class="line">        <span class="type">uint8_t</span> scl_pin;</span><br><span class="line">        <span class="type">uint8_t</span> addr;</span><br><span class="line">        <span class="type">i2c_port_t</span> i2c_num;</span><br><span class="line">    }i2c;<span class="comment">//存储bsp相关数据</span></span><br><span class="line"></span><br><span class="line">    <span class="type">touch_panel_dir_t</span> direction;</span><br><span class="line">    <span class="type">uint16_t</span> width;</span><br><span class="line">    <span class="type">uint16_t</span> height;</span><br><span class="line">} <span class="type">ft6236_dev_t</span>;</span><br></pre></td></tr></table></figure>

<h3 id="数据读写函数"><a href="#数据读写函数" class="headerlink" title="数据读写函数"></a>数据读写函数</h3><p>FT6236的读写时序如下：</p>
<p><img src="https://s21.ax1x.com/2024/08/13/pApbTaR.png" alt="image-20240813131948606"></p>
<ul>
<li>写寄存器</li>
</ul>
<p>开始-地址-寄存器地址-数据-结束</p>
<ul>
<li>读寄存器</li>
</ul>
<p>开始-地址-寄存器地址-结束</p>
<p>开始-地址-读数据-结束</p>
<p>使用IDF的IIC部分相关代码实现如下：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">uint8_t</span> <span class="title function_">ft6236_interface_init</span><span class="params">(<span class="type">ft6236_dev_t</span> *dev)</span></span><br><span class="line">{</span><br><span class="line"><span class="comment">//iic初始化，gpio初始化</span></span><br><span class="line">        <span class="type">esp_err_t</span> err=ESP_OK;</span><br><span class="line"></span><br><span class="line">    <span class="type">i2c_config_t</span> config={</span><br><span class="line">            .mode=I2C_MODE_MASTER,</span><br><span class="line">            .sda_io_num=dev-&gt;i2c.sda_pin,</span><br><span class="line">            .scl_io_num=dev-&gt;i2c.scl_pin,</span><br><span class="line">            .scl_pullup_en=GPIO_PULLUP_ENABLE,</span><br><span class="line">            .sda_pullup_en=GPIO_PULLUP_ENABLE,</span><br><span class="line">            .master.clk_speed=<span class="number">400000</span>,</span><br><span class="line">            .clk_flags=<span class="number">0</span></span><br><span class="line">    };</span><br><span class="line">    err |= i2c_param_config(dev-&gt;i2c.i2c_num,&amp;config);</span><br><span class="line">    err |= i2c_driver_install(dev-&gt;i2c.i2c_num,config.mode,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">//int_pin must be pulled up</span></span><br><span class="line">    <span class="keyword">if</span>(dev-&gt;int_pin != <span class="number">-1</span>) {</span><br><span class="line">        gpio_set_direction(dev-&gt;int_pin, GPIO_MODE_INPUT);</span><br><span class="line">        gpio_set_pull_mode(dev-&gt;int_pin, GPIO_PULLUP_ONLY);</span><br><span class="line">    }</span><br><span class="line">    <span class="comment">//rst_pin</span></span><br><span class="line">    <span class="keyword">if</span>(dev-&gt;rst_pin != <span class="number">-1</span>) {</span><br><span class="line">        gpio_set_direction(dev-&gt;rst_pin, GPIO_MODE_OUTPUT);</span><br><span class="line">        gpio_set_level(dev-&gt;rst_pin, <span class="number">0</span>);</span><br><span class="line">        vTaskDelay(<span class="number">400</span> / portTICK_PERIOD_MS);<span class="comment">//at last 300ms</span></span><br><span class="line">        gpio_set_level(dev-&gt;rst_pin, <span class="number">1</span>);</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> err;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">ft6236_interface_deinit</span><span class="params">(<span class="type">ft6236_dev_t</span> *dev)</span></span><br><span class="line">{</span><br><span class="line">    i2c_driver_delete(dev-&gt;i2c.i2c_num);</span><br><span class="line">    <span class="keyword">if</span>(dev-&gt;int_pin != <span class="number">-1</span>)</span><br><span class="line">        gpio_reset_pin(dev-&gt;int_pin);</span><br><span class="line">    <span class="keyword">if</span>(dev-&gt;rst_pin != <span class="number">-1</span>)</span><br><span class="line">        gpio_reset_pin(dev-&gt;rst_pin);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">uint8_t</span> <span class="title function_">ft6236_write_one_reg</span><span class="params">(<span class="type">ft6236_dev_t</span> *dev,<span class="type">uint8_t</span> start_addr,<span class="type">uint8_t</span> write_size,<span class="type">uint8_t</span> *data_buf)</span></span><br><span class="line">{</span><br><span class="line"><span class="comment">//按照时序写寄存器</span></span><br><span class="line">    <span class="type">esp_err_t</span> err=ESP_OK;</span><br><span class="line">    <span class="type">i2c_port_t</span> i2c_num=dev-&gt;i2c.i2c_num;</span><br><span class="line">    <span class="type">uint8_t</span> _data[<span class="number">2</span>]={start_addr,data};</span><br><span class="line"></span><br><span class="line">    <span class="type">i2c_cmd_handle_t</span> handle=i2c_cmd_link_create();</span><br><span class="line">    <span class="keyword">if</span>(handle==<span class="literal">NULL</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    i2c_master_start(handle);</span><br><span class="line">    i2c_master_write_byte(handle, (dev-&gt;i2c.addr &lt;&lt; <span class="number">1</span>) | I2C_MASTER_WRITE, <span class="literal">true</span>);</span><br><span class="line">    i2c_master_write(handle, _data, <span class="number">2</span>, <span class="literal">true</span>);</span><br><span class="line">    i2c_master_stop(handle);</span><br><span class="line">    err = i2c_master_cmd_begin(i2c_num, handle, <span class="number">1000</span>*portTICK_PERIOD_MS);</span><br><span class="line">    i2c_cmd_link_delete(handle);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> err==ESP_OK ? <span class="number">0</span>:<span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="type">static</span> <span class="type">uint8_t</span> <span class="title function_">ft6236_read_reg</span><span class="params">(<span class="type">ft6236_dev_t</span> *dev,<span class="type">uint8_t</span> start_addr,<span class="type">uint8_t</span> read_num,<span class="type">uint8_t</span> *data_buf)</span></span><br><span class="line">{</span><br><span class="line"><span class="comment">//按照时序读寄存器</span></span><br><span class="line">    <span class="type">esp_err_t</span> err=ESP_OK;</span><br><span class="line">    <span class="type">i2c_port_t</span> i2c_num=dev-&gt;i2c.i2c_num;</span><br><span class="line"></span><br><span class="line">    <span class="type">i2c_cmd_handle_t</span> handle=i2c_cmd_link_create();</span><br><span class="line">    <span class="keyword">if</span>(handle==<span class="literal">NULL</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="comment">//First, set the reg address</span></span><br><span class="line">    err|=i2c_master_start(handle);</span><br><span class="line">    err|=i2c_master_write_byte(handle, (dev-&gt;i2c.addr &lt;&lt; <span class="number">1</span>) | I2C_MASTER_WRITE, <span class="literal">true</span>);</span><br><span class="line">    err|=i2c_master_write_byte(handle, start_addr, <span class="literal">true</span>);</span><br><span class="line">    err|=i2c_master_stop(handle);</span><br><span class="line">    err|=i2c_master_cmd_begin(i2c_num, handle, <span class="number">1000</span>/portTICK_PERIOD_MS);</span><br><span class="line">    i2c_cmd_link_delete(handle);</span><br><span class="line">    <span class="keyword">if</span>(err!=ESP_OK) <span class="keyword">return</span> <span class="number">1</span>;<span class="comment">//return if error</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">//then read data</span></span><br><span class="line">    handle=i2c_cmd_link_create();</span><br><span class="line">    <span class="keyword">if</span>(handle==<span class="literal">NULL</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    err|=i2c_master_start(handle);</span><br><span class="line">    err|=i2c_master_write_byte(handle, (dev-&gt;i2c.addr &lt;&lt; <span class="number">1</span>) | I2C_MASTER_READ, <span class="literal">true</span>);</span><br><span class="line">    err|=i2c_master_read(handle, data_buf, read_num,I2C_MASTER_LAST_NACK);</span><br><span class="line">    err|=i2c_master_stop(handle);</span><br><span class="line">    err|=i2c_master_cmd_begin(i2c_num, handle, <span class="number">1000</span>/portTICK_PERIOD_MS);</span><br><span class="line">    i2c_cmd_link_delete(handle);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> err==ESP_OK ? <span class="number">0</span>:<span class="number">1</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>

<p>上面的函数是整个驱动的底层，进行移植时需要重新编写移植这些代码。</p>
<h3 id="芯片寄存器"><a href="#芯片寄存器" class="headerlink" title="芯片寄存器"></a>芯片寄存器</h3><p>查看芯片的datasheet，可以看到芯片的寄存器</p>
<p><img src="https://s21.ax1x.com/2024/08/13/pApb7I1.png" alt="image-20240501211125962"></p>
<p><img src="https://s21.ax1x.com/2024/08/13/pApbbPx.png" alt="image-20240501211137170"></p>
<p>这里注意几个比较重要的寄存器:</p>
<ul>
<li>P1_xxx: 触摸点数据寄存器。</li>
</ul>
<p>Event Flag说明了触摸点的数据：00b-按下，01b-松开，10b-Contact，11b-No event。</p>
<p>Touch ID说明是第几个触摸点,当点不可用时，值为0x0F。</p>
<p>WEIGHT存储了触摸点的按压力度。</p>
<ul>
<li>GEST_ID</li>
</ul>
<p>存储了触摸手势的判断：</p>
<p>0x10——Move Up</p>
<p>0x14——Move Right</p>
<p>0x18——Move Down</p>
<p>0x1C——Move Left</p>
<p>0x48——Zoom In</p>
<p>0x49——Zoom Out</p>
<p>0x00——No Gesture</p>
<ul>
<li>TD_STATUS</li>
</ul>
<p>存储了触摸点数量，有效值为1-2。</p>
<ul>
<li>TD_GROUP</li>
</ul>
<p>触摸检测阈值设置，越小越灵敏。</p>
<ul>
<li>G_MODE</li>
</ul>
<p>中断引脚模式。</p>
<p>polling mode：当有触摸数据时，引脚一直为低。</p>
<p>trigger mode：有触摸数据时，引脚会有一个有效电平低的脉冲。</p>
<h3 id="ESP-IDF触摸屏的驱动框架"><a href="#ESP-IDF触摸屏的驱动框架" class="headerlink" title="ESP-IDF触摸屏的驱动框架"></a>ESP-IDF触摸屏的驱动框架</h3><p>ESP组件库中有一个触摸屏驱动库，但是很不幸，该库中没有FT6236的驱动，因此需要根据其驱动框架编写FT6236的驱动。</p>
<h4 id="用户数据结构"><a href="#用户数据结构" class="headerlink" title="用户数据结构"></a>用户数据结构</h4><p>驱动库需要定义一些外部的数据结构，用来给用户读取和设置驱动。</p>
<p><strong>触摸板方向设置</strong></p>
<p>该设置用于改变驱动输出坐标的原点位置。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">enum</span> {</span></span><br><span class="line">    <span class="comment">/* @---&gt; X</span></span><br><span class="line"><span class="comment">       |</span></span><br><span class="line"><span class="comment">       Y</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_LRTB,   <span class="comment">/**&lt; From left to right then from top to bottom, this consider as the original direction of the touch panel*/</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/*  Y</span></span><br><span class="line"><span class="comment">        |</span></span><br><span class="line"><span class="comment">        @---&gt; X</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_LRBT,   <span class="comment">/**&lt; From left to right then from bottom to top */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* X &lt;---@</span></span><br><span class="line"><span class="comment">             |</span></span><br><span class="line"><span class="comment">             Y</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_RLTB,   <span class="comment">/**&lt; From right to left then from top to bottom */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/*       Y</span></span><br><span class="line"><span class="comment">             |</span></span><br><span class="line"><span class="comment">       X &lt;---@</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_RLBT,   <span class="comment">/**&lt; From right to left then from bottom to top */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* @---&gt; Y</span></span><br><span class="line"><span class="comment">       |</span></span><br><span class="line"><span class="comment">       X</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_TBLR,   <span class="comment">/**&lt; From top to bottom then from left to right */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/*  X</span></span><br><span class="line"><span class="comment">        |</span></span><br><span class="line"><span class="comment">        @---&gt; Y</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_BTLR,   <span class="comment">/**&lt; From bottom to top then from left to right */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/* Y &lt;---@</span></span><br><span class="line"><span class="comment">             |</span></span><br><span class="line"><span class="comment">             X</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_TBRL,   <span class="comment">/**&lt; From top to bottom then from right to left */</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">/*       X</span></span><br><span class="line"><span class="comment">             |</span></span><br><span class="line"><span class="comment">       Y &lt;---@</span></span><br><span class="line"><span class="comment">    */</span></span><br><span class="line">    TOUCH_DIR_BTRL,   <span class="comment">/**&lt; From bottom to top then from right to left */</span></span><br><span class="line"></span><br><span class="line">    TOUCH_DIR_MAX</span><br><span class="line">} <span class="type">touch_panel_dir_t</span>;</span><br></pre></td></tr></table></figure>

<p><strong>触摸事件</strong></p>
<p>该数据结构表示了触摸点的触摸事件，是按下还是松开。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">enum</span> {</span></span><br><span class="line">    TOUCH_EVT_PRESS   = <span class="number">0x0</span>,  <span class="comment">/*!&lt; Press event */</span></span><br><span class="line">    TOUCH_EVT_RELEASE = <span class="number">0x1</span>,  <span class="comment">/*!&lt; Release event */</span></span><br><span class="line">    TOUCH_EVT_CONTACT = <span class="number">0x2</span>,  <span class="comment">/*!&lt; Contact event */</span></span><br><span class="line">    TOUCH_EVT_NONE = <span class="number">0x3</span>,  <span class="comment">/*!&lt; no event */</span></span><br><span class="line">} <span class="type">touch_panel_event_t</span>;</span><br></pre></td></tr></table></figure>

<p><strong>触摸手势</strong></p>
<p>有些触摸屏可以检测触摸手势，而FT6236能够检测6种手势。驱动提供了一个数据结构用来描述。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">enum</span> {</span></span><br><span class="line">    TOUCH_GES_NONE = <span class="number">0x00</span>,  <span class="comment">/*!&lt; No Gesture */</span></span><br><span class="line">    TOUCH_GES_MOVE_UP = <span class="number">0x10</span>,  <span class="comment">/*!&lt; Move up */</span></span><br><span class="line">    TOUCH_GES_MOVE_RIGHT = <span class="number">0x14</span>,  <span class="comment">/*!&lt; Move right */</span></span><br><span class="line">    TOUCH_GES_MOVE_DOWN = <span class="number">0x18</span>,  <span class="comment">/*!&lt; Move down */</span></span><br><span class="line">    TOUCH_GES_MOVE_LEFT = <span class="number">0x1C</span>, <span class="comment">/*!&lt; Move left */</span></span><br><span class="line">    TOUCH_GES_ZOOM_IN   = <span class="number">0x48</span>, <span class="comment">/*!&lt; Zoom in */</span></span><br><span class="line">    TOUCH_GES_ZOOM_OUT  = <span class="number">0x49</span>, <span class="comment">/*!&lt; Zoom out */</span></span><br><span class="line">} touch_panel_gesture;</span><br></pre></td></tr></table></figure>

<p><strong>触摸屏配置结构体</strong></p>
<p>用来传入配置参数的结构体。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line">    <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line">        <span class="type">uint8_t</span> addr;                              <span class="comment">/*!&lt; dev's address */</span></span><br><span class="line">        <span class="type">i2c_port_t</span> i2c_num;                        <span class="comment">/*!&lt; i2c port to use */</span></span><br><span class="line">        <span class="type">uint8_t</span> i2c_scl;                           <span class="comment">/*!&lt; i2c scl pin */</span></span><br><span class="line">        <span class="type">uint8_t</span> i2c_sda;                           <span class="comment">/*!&lt; i2c sda pin */</span></span><br><span class="line">    }i2c;                                          <span class="comment">/*!&lt; i2c bsp config */</span></span><br><span class="line">    <span class="type">int8_t</span> pin_num_int;                            <span class="comment">/*!&lt; Interrupt pin of touch panel. <span class="doctag">NOTE:</span> You can set to -1 for no connection with hardware. If PENIRQ is connected, set this to pin number. */</span></span><br><span class="line">    <span class="type">int8_t</span> pin_num_rst;                            <span class="comment">/*!&lt; rst pin  */</span></span><br><span class="line">    <span class="type">touch_panel_dir_t</span> direction;                   <span class="comment">/*!&lt; Rotate direction */</span></span><br><span class="line">    <span class="type">uint16_t</span> width;                                <span class="comment">/*!&lt; touch panel width */</span></span><br><span class="line">    <span class="type">uint16_t</span> height;                               <span class="comment">/*!&lt; touch panel height */</span></span><br><span class="line">} <span class="type">touch_panel_config_t</span>;</span><br></pre></td></tr></table></figure>

<p><strong>触摸点信息</strong></p>
<p>用于驱动向用户传递触摸点信息。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> {</span></span><br><span class="line">    <span class="type">uint8_t</span> point_num;           <span class="comment">/*!&lt; Touch point number */</span></span><br><span class="line">    touch_panel_gesture gesture; <span class="comment">/*!&lt; Gesture of touch */</span></span><br><span class="line">    <span class="type">touch_panel_event_t</span> event[TOUCH_MAX_POINT_NUMBER];   <span class="comment">/*!&lt; Event of touch */</span></span><br><span class="line">    <span class="type">uint8_t</span> weight[TOUCH_MAX_POINT_NUMBER];             <span class="comment">/*!&lt; weight of touch */</span></span><br><span class="line">    <span class="type">uint16_t</span> curx[TOUCH_MAX_POINT_NUMBER];            <span class="comment">/*!&lt; Current x coordinate */</span></span><br><span class="line">    <span class="type">uint16_t</span> cury[TOUCH_MAX_POINT_NUMBER];            <span class="comment">/*!&lt; Current y coordinate */</span></span><br><span class="line">} <span class="type">touch_panel_points_t</span>;</span><br></pre></td></tr></table></figure>

<h4 id="内部数据结构"><a href="#内部数据结构" class="headerlink" title="内部数据结构"></a>内部数据结构</h4><p>驱动内部使用一个结构体用来代指一个设备，该结构体已经在上面给出。</p>
<h4 id="用户函数"><a href="#用户函数" class="headerlink" title="用户函数"></a>用户函数</h4><p>驱动需要实现以下函数：</p>
<p><strong>初始化与反初始化函数</strong></p>
<p>初始化内部的设备结构体，同时初始化相关外设以及相关的寄存器。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">uint8_t</span> <span class="title function_">ft6236_init</span><span class="params">(<span class="type">touch_panel_config_t</span> *config)</span></span><br><span class="line">{</span><br><span class="line">    <span class="type">uint8_t</span> ret=<span class="number">0</span>;</span><br><span class="line">    <span class="type">uint8_t</span> cipher=<span class="number">0</span>;<span class="comment">//must be 0x64</span></span><br><span class="line">    <span class="type">uint8_t</span> firmid=<span class="number">0</span>;<span class="comment">//Firmware Version</span></span><br><span class="line">    <span class="type">uint8_t</span> data=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    g_dev.i2c.addr=config-&gt;i2c.addr;</span><br><span class="line">    g_dev.i2c.i2c_num=config-&gt;i2c.i2c_num;</span><br><span class="line">    g_dev.i2c.scl_pin=config-&gt;i2c.i2c_scl;</span><br><span class="line">    g_dev.i2c.sda_pin=config-&gt;i2c.i2c_sda;</span><br><span class="line">    g_dev.int_pin=config-&gt;pin_num_int;</span><br><span class="line">    g_dev.rst_pin=config-&gt;pin_num_rst;</span><br><span class="line">    g_dev.width=config-&gt;width;</span><br><span class="line">    g_dev.height=config-&gt;height;</span><br><span class="line">    ft6236_set_direction(config-&gt;direction);</span><br><span class="line">    <span class="comment">//bsp initialize and test</span></span><br><span class="line">    ret += ft6236_interface_init(&amp;g_dev);</span><br><span class="line">    ret += ft6236_read_reg(&amp;g_dev,FT6236_REG_FIRMID,<span class="number">1</span>,&amp;firmid);</span><br><span class="line">    ret += ft6236_read_reg(&amp;g_dev,FT6236_REG_CIPHER,<span class="number">1</span>,&amp;cipher);</span><br><span class="line">    <span class="keyword">if</span>(ret!=<span class="number">0</span> ||cipher!=<span class="number">0x64</span>)<span class="comment">//chip id changes with chips</span></span><br><span class="line">    {</span><br><span class="line">        ESP_LOGI(TAG,<span class="string">"Initialize interface fail.cipher=%x firmware version=%x."</span>,cipher,firmid);</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    }</span><br><span class="line">    ESP_LOGI(TAG,<span class="string">"cipher=%x firmware version=%x."</span>,cipher,firmid);</span><br><span class="line">    <span class="comment">//set the interrupt mod to polling(continuous low level)</span></span><br><span class="line">    data=<span class="number">0</span>;</span><br><span class="line">    ret += ft6236_write_one_reg(&amp;g_dev, FT6236_REG_G_MODE, data);</span><br><span class="line">    <span class="comment">//set the touch detect threshold(lower is sensitive)</span></span><br><span class="line">    data=<span class="number">22</span>;</span><br><span class="line">    ret += ft6236_write_one_reg(&amp;g_dev, FT6236_REG_TH_GROUP, data);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> ret;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>

<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">void ft6236_deinit(void)</span><br><span class="line">{</span><br><span class="line">    ft6236_interface_deinit(&amp;g_dev);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>

<p><strong>坐标方向设置函数</strong></p>
<p>用于改变屏幕方向。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">uint8_t</span> <span class="title function_">ft6236_set_direction</span><span class="params">(<span class="type">touch_panel_dir_t</span> dir)</span> {</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (TOUCH_DIR_MAX &lt; dir) {</span><br><span class="line">        dir &gt;&gt;= <span class="number">5</span>;</span><br><span class="line">    }</span><br><span class="line">    g_dev.direction = dir;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>

<p><strong>查询与数据获取</strong></p>
<p>通过int引脚或者读取寄存器来判断是否有触摸点。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * confirm if there is touch event</span></span><br><span class="line"><span class="comment"> * @return 1:touched 0:nothing</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="type">uint8_t</span> <span class="title function_">ft6236_is_press</span><span class="params">(<span class="type">void</span>)</span></span><br><span class="line">{</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @note There are two ways to determine weather the touch panel is pressed</span></span><br><span class="line"><span class="comment"> * 1. Read the IRQ line of touch controller</span></span><br><span class="line"><span class="comment"> * 2. Read number of points touched in the register</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="number">-1</span> != g_dev.int_pin) {</span><br><span class="line">        <span class="keyword">return</span> !gpio_get_level((<span class="type">gpio_num_t</span>)g_dev.int_pin);</span><br><span class="line">    }</span><br><span class="line">    <span class="type">uint8_t</span> num;</span><br><span class="line">    ft6236_read_reg(&amp;g_dev,FT6236_REG_TD_STATUS,<span class="number">1</span>,&amp;num);</span><br><span class="line">    <span class="keyword">if</span>((num&amp;<span class="number">0x07</span>) ==<span class="number">0</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>

<p>数据点信息读取：</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">uint8_t</span> <span class="title function_">ft6236_get_points</span><span class="params">(<span class="type">touch_panel_points_t</span> *info)</span></span><br><span class="line">{</span><br><span class="line">    <span class="type">uint8_t</span> data_buf[<span class="number">14</span>];</span><br><span class="line">    <span class="type">uint8_t</span> point_index=<span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">    ft6236_read_reg(&amp;g_dev,FT6236_REG_GEST_ID,<span class="number">14</span>,data_buf);</span><br><span class="line"></span><br><span class="line">    info-&gt;point_num =data_buf[<span class="number">1</span>] &amp;<span class="number">0x07</span>;<span class="comment">//get TD_STATUS</span></span><br><span class="line">    <span class="keyword">if</span> (info-&gt;point_num &gt; <span class="number">0</span> &amp;&amp; info-&gt;point_num &lt;= TOUCH_MAX_POINT_NUMBER) {</span><br><span class="line">        info-&gt;gesture=data_buf[<span class="number">0</span>];<span class="comment">//get the gesture ID</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(data_buf[<span class="number">4</span>]&gt;&gt;<span class="number">4</span>!=<span class="number">0x0F</span>)<span class="comment">//Touch ID is valid</span></span><br><span class="line">        {</span><br><span class="line">            info-&gt;event[point_index] = data_buf[<span class="number">2</span>] &gt;&gt; <span class="number">6</span>;</span><br><span class="line">            info-&gt;curx[point_index] = (((<span class="type">uint16_t</span>)(data_buf[<span class="number">2</span>]&amp;<span class="number">0x0F</span>) &lt;&lt; <span class="number">8</span>) | data_buf[<span class="number">3</span>]);</span><br><span class="line">            info-&gt;cury[point_index] = (((<span class="type">uint16_t</span>)(data_buf[<span class="number">4</span>]&amp;<span class="number">0x0F</span>) &lt;&lt; <span class="number">8</span>) | data_buf[<span class="number">5</span>]);</span><br><span class="line">            info-&gt;weight[point_index] = data_buf[<span class="number">6</span>];</span><br><span class="line">            ft6236_apply_rotate(&amp;info-&gt;curx[point_index],&amp;info-&gt;cury[point_index]);</span><br><span class="line"></span><br><span class="line">            point_index++;</span><br><span class="line">        }</span><br><span class="line">        <span class="keyword">if</span>(data_buf[<span class="number">10</span>]&gt;&gt;<span class="number">4</span>!=<span class="number">0x0F</span>)<span class="comment">//Touch ID is valid</span></span><br><span class="line">        {</span><br><span class="line">            info-&gt;event[point_index] = data_buf[<span class="number">8</span>] &gt;&gt; <span class="number">6</span>;</span><br><span class="line">            info-&gt;curx[point_index] = (((<span class="type">uint16_t</span>)(data_buf[<span class="number">8</span>]&amp;<span class="number">0x0F</span>) &lt;&lt; <span class="number">8</span>) | data_buf[<span class="number">9</span>]);</span><br><span class="line">            info-&gt;cury[point_index] = (((<span class="type">uint16_t</span>)(data_buf[<span class="number">10</span>]&amp;<span class="number">0x0F</span>) &lt;&lt; <span class="number">8</span>) | data_buf[<span class="number">11</span>]);</span><br><span class="line">            info-&gt;weight[point_index] = data_buf[<span class="number">12</span>];</span><br><span class="line">            ft6236_apply_rotate(&amp;info-&gt;curx[point_index],&amp;info-&gt;cury[point_index]);</span><br><span class="line"></span><br><span class="line">            point_index++;</span><br><span class="line">        }</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span>(point_index==<span class="number">1</span>){<span class="comment">//clean the unused info</span></span><br><span class="line">            info-&gt;curx[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line">            info-&gt;cury[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line">        }</span><br><span class="line"><span class="comment">//        ESP_LOGI(TAG,"Touch ID--1:%x,2:%x",data_buf[4],data_buf[10]);</span></span><br><span class="line">        <span class="keyword">return</span> info-&gt;point_num;</span><br><span class="line">    } <span class="keyword">else</span> {</span><br><span class="line">        info-&gt;curx[<span class="number">0</span>] = <span class="number">0</span>;</span><br><span class="line">        info-&gt;cury[<span class="number">0</span>] = <span class="number">0</span>;</span><br><span class="line">        info-&gt;curx[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line">        info-&gt;cury[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>

<h4 id="内部函数"><a href="#内部函数" class="headerlink" title="内部函数"></a>内部函数</h4><p>内部函数是驱动中需要使用的一些功能，除了上面的interface_init和reg读取，还有不同触摸屏方向下坐标的换算。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">static</span> <span class="type">void</span> <span class="title function_">ft6236_apply_rotate</span><span class="params">(<span class="type">uint16_t</span> *x, <span class="type">uint16_t</span> *y)</span></span><br><span class="line">{</span><br><span class="line">    <span class="type">uint16_t</span> _x = *x;</span><br><span class="line">    <span class="type">uint16_t</span> _y = *y;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">switch</span> (g_dev.direction) {</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_LRTB:</span><br><span class="line">            *x = _x;</span><br><span class="line">            *y = _y;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_LRBT:</span><br><span class="line">            *x = _x;</span><br><span class="line">            *y = g_dev.height - _y;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_RLTB:</span><br><span class="line">            *x = g_dev.width - _x;</span><br><span class="line">            *y = _y;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_RLBT:</span><br><span class="line">            *x = g_dev.width - _x;</span><br><span class="line">            *y = g_dev.height - _y;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_TBLR:</span><br><span class="line">            *x = _y;</span><br><span class="line">            *y = _x;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_BTLR:</span><br><span class="line">            *x = _y;</span><br><span class="line">            *y = g_dev.width - _x;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_TBRL:</span><br><span class="line">            *x = g_dev.height - _y;</span><br><span class="line">            *y = _x;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">        <span class="keyword">case</span> TOUCH_DIR_BTRL:</span><br><span class="line">            *x = g_dev.height - _y;</span><br><span class="line">            *y = g_dev.width - _x;</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">default</span>:</span><br><span class="line">            <span class="keyword">break</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>








        </div>
        
<blockquote class="copyright">
    <p><strong>本文链接 : </strong><a class="permalink" href="https://lostacnet.top/post/43032/">https://lostacnet.top/post/43032/</a></p>
    <p><strong>This article is available under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank" rel="noopener noreferrer">Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)</a> License  转载请注明出处</strong></p>
</blockquote>


    </article>
    
    <section id="comments">
        
    </section>


    

</main>


<aside style="" id="sidebar" class="aside aside-fixture">
    <div class="toc-sidebar">
        <nav id="toc" class="article-toc">
            <h3 class="toc-title">文章目录</h3>
            <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#ESP-IDF%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0-IIC%E4%B8%8EFT6236%E8%A7%A6%E6%91%B8%E5%B1%8F"><span class="toc-number">1.</span> <span class="toc-text">ESP-IDF学习笔记-IIC与FT6236触摸屏</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3"><span class="toc-number">1.1.</span> <span class="toc-text">官方文档</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#IDF%E7%9A%84IIC%E9%A9%B1%E5%8A%A8"><span class="toc-number">1.2.</span> <span class="toc-text">IDF的IIC驱动</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%89%88%E6%9C%AC%E5%8F%98%E6%9B%B4"><span class="toc-number">1.2.1.</span> <span class="toc-text">版本变更</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%85%8D%E7%BD%AE%E9%A9%B1%E5%8A%A8%E7%A8%8B%E5%BA%8F"><span class="toc-number">1.2.2.</span> <span class="toc-text">配置驱动程序</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%89%E8%A3%85%E9%A9%B1%E5%8A%A8%E7%A8%8B%E5%BA%8F"><span class="toc-number">1.2.3.</span> <span class="toc-text">安装驱动程序</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%B8%BB%E6%9C%BA%E6%A8%A1%E5%BC%8F%E4%B8%8B%E7%9A%84%E9%80%9A%E4%BF%A1"><span class="toc-number">1.2.4.</span> <span class="toc-text">主机模式下的通信</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%BB%E6%9C%BA%E5%86%99%E5%85%A5%E6%95%B0%E6%8D%AE"><span class="toc-number">1.2.4.1.</span> <span class="toc-text">主机写入数据</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E4%B8%BB%E6%9C%BA%E8%AF%BB%E5%8F%96%E6%95%B0%E6%8D%AE"><span class="toc-number">1.2.4.2.</span> <span class="toc-text">主机读取数据</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%A0%E9%99%A4%E9%A9%B1%E5%8A%A8"><span class="toc-number">1.2.5.</span> <span class="toc-text">删除驱动</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%85%B6%E4%BB%96%E8%AF%BB%E5%86%99%E5%87%BD%E6%95%B0"><span class="toc-number">1.2.6.</span> <span class="toc-text">其他读写函数</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#FT6236"><span class="toc-number">1.3.</span> <span class="toc-text">FT6236</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%BC%95%E8%84%9A%E5%AE%9A%E4%B9%89"><span class="toc-number">1.3.1.</span> <span class="toc-text">引脚定义</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%BE%E5%A4%87%E7%BB%93%E6%9E%84%E4%BD%93"><span class="toc-number">1.3.2.</span> <span class="toc-text">设备结构体</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%95%B0%E6%8D%AE%E8%AF%BB%E5%86%99%E5%87%BD%E6%95%B0"><span class="toc-number">1.3.3.</span> <span class="toc-text">数据读写函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%8A%AF%E7%89%87%E5%AF%84%E5%AD%98%E5%99%A8"><span class="toc-number">1.3.4.</span> <span class="toc-text">芯片寄存器</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#ESP-IDF%E8%A7%A6%E6%91%B8%E5%B1%8F%E7%9A%84%E9%A9%B1%E5%8A%A8%E6%A1%86%E6%9E%B6"><span class="toc-number">1.3.5.</span> <span class="toc-text">ESP-IDF触摸屏的驱动框架</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%94%A8%E6%88%B7%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84"><span class="toc-number">1.3.5.1.</span> <span class="toc-text">用户数据结构</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%86%85%E9%83%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84"><span class="toc-number">1.3.5.2.</span> <span class="toc-text">内部数据结构</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%94%A8%E6%88%B7%E5%87%BD%E6%95%B0"><span class="toc-number">1.3.5.3.</span> <span class="toc-text">用户函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%86%85%E9%83%A8%E5%87%BD%E6%95%B0"><span class="toc-number">1.3.5.4.</span> <span class="toc-text">内部函数</span></a></li></ol></li></ol></li></ol></li></ol>
        </nav>
    </div>
</aside>





        </section>
        <footer class="hidden lg:block fixed bottom-0 left-0 sm:w-1/12 lg:w-1/6 bg-gray-100 z-40">
    
    <div class="footer-social-links">
        
            <a target="_blank" rel="noopener" href="https://github.com/LOStacNet">
                <i class="iconfont icon-github"></i>
            </a>
        
            <a target="_blank" rel="noopener" href="https://gitee.com/LOStacNet">
                <i class="iconfont icon-project"></i>
            </a>
        
    </div>
    
    
</footer>

        <div id="mask" class="hidden mask fixed inset-0 bg-gray-900 opacity-75 z-40"></div>
        <div id="search-view-container" class="hidden shadow-xl"></div>
        
<script src="/js/dom-event.min.js"></script>



<script src="/js/local-search.min.js"></script>



    <script src="//cdn.jsdelivr.net/npm/lightgallery.js@1.1.3/dist/js/lightgallery.min.js"></script>
    
<script src="/js/light-gallery.min.js"></script>






    </body>
</html>
